#pragma once
#include "ASTree.h"
#include "clang-c\index.h"
#include <unordered_set>
//#include "boost\graph\adjacency_list.hpp"
//#include "stdAfx.h"
//#include "ASTreeCommon.h"

namespace AST{
	
typedef std::unordered_multiset<unsigned int> ngramSet;

class Node
{
public:
	Node();
	Node(CXCursor cxcursor, unsigned long nodeId, std::string NodeName, ASTree*  ownerTree);
	~Node(void);

	//member fields
	const CXCursor cursor;
	const unsigned long id;
	const ASTree* tree;
	const std::string nodeName;

	//member methods
	void setVertex (vertexDesc vertex);
	vertexDesc& getVertex (void);
	void leaf (bool isLeaf);
	bool leaf ();
	std::string& nodeSource();
	void nodeSource(std::string source);
	//static methods
	static Node* createNode(CXCursor cxcursor, unsigned long nodeId, std::string nodeName, ASTree*  ownerTree);
	CXCursorKind getKind();
	float match (Node& node);

	//static members
	static const unsigned int ngramWindowSize = 3;

protected:
	//member fields
	bool isLeaf;
	std::string sourceSnippet;
	ngramSet* ngrams;
	//member methods
	boost::graph_traits<Graph>::vertex_descriptor nodeVertex; 
	static float ngramSimilarity(const ngramSet* A, const ngramSet* B);
	ngramSet const * getNgrams(unsigned int windowSize);
};

class GenericNode : public Node
{
public:
	GenericNode();
	GenericNode(CXCursor cxcursor, unsigned long nodeId, std::string nodeName, ASTree*  ownerTree);
	~GenericNode(void);
};

class ClassDeclNode : public GenericNode
{
public:
	ClassDeclNode();
	ClassDeclNode(CXCursor cxcursor, unsigned long nodeId, std::string nodeName, ASTree*  ownerTree);
	~ClassDeclNode(void);
};

class TranslationUnitNode : public GenericNode
{
public:
	TranslationUnitNode();
	TranslationUnitNode(CXCursor cxcursor, unsigned long nodeId, std::string nodeName, ASTree*  ownerTree);
	~TranslationUnitNode(void);
};

} //namespace AST